# ------------------------
# - Removed tweets to user function. !log <twitter> <text> now tweets to @indiatwit, otherwise just clips (11/5/08)
# ------------------------

import irclib
import re
import time
import simplejson
import twitter

#irclib.DEBUG = True

# Connection information
network = 'irc.freenode.net'
port = 6667
channel = '#indiatwits'
nick = ''
pass_ = ""
name = ''
path = ""
to = twitter.Api('indiatwits', 'indiatwits')
authed = {}
maps = {}
last_update = time.localtime()

def pubMSG(connection, event):
	ev = event.arguments()[0];
	fr = event.source().split('!')[0] # to separate nick from the entire address

	if ev.startswith('!'):
		m = re.match('^!(\w+)[ ]?(.*)', ev)
		func = m.group(1)
		arg = m.group(2)
		if (func == "addo") & (arg != ""): # to add to ops
			add_to_ops(fr, arg)
			return
			
		if (func == "addv") & (arg != ""): # to add to voice
			add_to_voice(fr, arg)
			return
		
		if (func == 'log') & (arg != ""): # to clip
			log(fr, arg)
			return
		
		if (func == 'gl') & (arg != ""): # to retrieve clips
			getlog(arg)
			return
		
		if (func == 'topic') & (arg != ""): # set the topic
			topic(fr, arg)
			return
		
		if (func == 'help'): # get help
			showHelp(connection, fr, arg)
			return
		
		if (func == 'map') & (arg != ""):
			ret = map(fr, arg)
			if ret == 1:
				msgServer( "[Nicknames mapped]")
			elif ret == 0:
				msgServer( "[Only Ops can map]")
			else:
				msgServer( "[Nicknames couldn't be mapped]")
			return
		
		if func == 'dc':
			if file(path + '\ops.log').read().find(fr) != -1:
				server.disconnect()
				exit()


def add_to_ops(fr, nick):
	p = path + '\ops.log'
	f = open(p, 'a')
	fa = file(p).read()

	if fa.find(fr) != -1: # initiator is an op
		if fa.find(nick) != -1:
			msgServer( "[" + nick + " already in list]" )
			return

		ops = " " + nick # space separated list
		f.write(ops)
		f.close()
		server.mode(channel, "o " + nick) # op the user
		msgServer( "[" + nick + " was added to Ops list]" )
	else:
		msgServer( "[Only operators can add to list]" )

def add_to_voice(fr, nick): # same as above
	p = path + '\ov.log'
	f = open(p, 'a')
	fa = file(p).read()

	if file(path + '\ops.log').read().find(fr) != -1: #initiator is an op
		if fa.find(nick) != -1:
			msgServer( "[" + nick + " already in list]" )
			return

		ops = " " + nick
		f.write(ops)
		f.close()
		server.mode(channel, "v " + nick)
		msgServer( "[" + nick + " was added to Voice list]" )
	else:
		msgServer( "[Only operators can add to list]" )

def log(nick, text):
	curr_time = time.strftime('%d-%m-%y') # current date for private log
	p = path + '\clips.log'
	f = open(p, 'a')
	flag = 0
	
	tw = re.match("(twitter)?[ ]?(.*)", text) # analyze 'text' for <twitter>
	to_tweet = tw.group(2).lstrip() # map the string once
	
	if tw.group(1) == "twitter":
		if haveAccess(nick):
			to_st = to.PostUpdate( urlenc( mapIt(to_tweet, 0) + " (" + mapIt(nick, 1) + ")" ))
			flag = 1
		else:
			msgServer("[Sorry, only operators and voiced users can tweet]")
	
	f.write(to_tweet + ' [' + str(curr_time) + ' / ' + nick + ']' + "\n") # write to file
	f.close()
		
	if flag == 1:
		msgServer( "[Clip saved and tweeted at " + str(curr_time) + "]")
	else:
		msgServer( "[Clip saved at " + str(curr_time) + "]")

def getlog(key):
	p = path + '\clips.log'
	f = open(p, 'r')
	flag = 1
	c = 0
	m = 0
	
	msgServer( "-----------------------")
	while True:
		line = f.readline()
		if line == '':
			break
		
		if line.lower().find(key.lower()) != -1:
			if c <= 7:
				msgServer( line)
				c = c + 1
				time.sleep(1)
			else:
				c = c + 1
				flag = 1
	# end of while
	
	if c >= 7:
		m = 7
		more = "Full list <http://summize.com/search?q=" + key + "+from:indiatwits> "
	else:
		m = c
		more = ""
	
	if flag == 0:
		msgServer( "-- Sorry, no logs found --")
	else:
		msgServer( "--- " + str(m) +" / " + str(c) + " log(s) shown. " + more + "---")

def topic(fr, text): # set the topic
	if file(path + '\ops.log').read().find(fr) != -1:
		status = to.PostUpdate("Discussing: " + text + ". Join us http://is.gd/dRD")
		topic = "Welcome to IndiaTwits! The Hangout of the Indian Twitter Community :) Current Topic: "+ text +" // Learn More about IndiaTwits at <http://is.gd/dRD> Join the IndiaTwits Folding@Home Team. More at <http://lin.cr/nq>. Follow @indiatwits on Twitter to get regular updates. Enjoy your stay!"
		server.topic(channel, topic)
	else:
		server.privmsg (channel, "[Sorry, Ops only]")

def auto_works(connection, event): # on new user join actions
	fr = event.source().split('!')[0]
	if file(path + '\ops.log').read().find(fr) != -1:
		server.mode(channel, 'o ' + fr)
		return

	if file(path + '\ov.log').read().find(fr) != -1:
		server.mode(channel, 'v ' + fr)
		return

# All mapping functions
def map(nick, arg):
	if haveAccess(nick) == 0:
		return 0
	nicks = arg.split(' ')
	log_text = nicks[0] + ":" + nicks[1] + "\n"
	f = open(path + '\maps.log', 'a')
	f.write(log_text)
	f.close()
	return 1

def mapUpd(connection, event):
	nicks = file(path + "\maps.log").read().split("\n")
	for line in nicks:
		if line.find(":") != -1:
			line = line.split(":")
			maps.update({line[0]:line[1]})

def mapIt(text, at):
	if at:
		rep = "@"
	else:
		rep = ""
	for m in maps:
		text = text.replace(m, rep + maps[m])
	return text

def showHelp(connection, nick, on): # show help
	msgServer( "@"+nick+": Please check your query window")
	cmds = { 
		"register":"""-- type in: /ns register <password>
-- to log in, type in: /ns identify <password>""",
		"ghost":"""-- to kill the ghost nick: /ns ghost <nick> <password>
-- change your nickname to the original, then log in: /ns identify <password>""",
		"auth":"""-- to authorize yourself with itbot for tweeting, type: /msg itbot auth <user> <pass>
-- [Disclaimer] Details are for auth only, and are not stored. Your nick must be registered (!help register) for this"""
	}
	if on != "":
		if cmds.has_key(on):
			for line in cmds[on].split("\n"):
				connection.privmsg(nick, line)

	else:
		help = """-- addo <nick> : Adds nickname to Ops list
-- addv <nick> : Adds nickname to auto Voice list
-- gl <keyword> : Searches logs for keyword and retrieves
-- help : Shows this
-- log <twitter> <text> : Logs text to memory / Add 'twitter' to tweet the log as well
-- topic <text> : Set the topic"""
		for line in help.split("\n"):
			connection.privmsg(nick, line)
			time.sleep(1)

# Other functions
def urlenc(str):
	return str.replace('<', '&lt;').replace('>', '&gt;')

def haveAccess(nick):
	access = (file(path + '\ops.log').read().find(nick) != -1) | (file(path + '\ov.log').read().find(nick) != -1) # only for ops and voice
	if access:
		return 1
	else:
		return 0

def msgServer(text):
	server.privmsg( channel, text )

# Create an IRC object
irc = irclib.IRC()

# Register handlers (should be before server connections)
irc.add_global_handler('pubmsg', pubMSG)
irc.add_global_handler('join',auto_works)
irc.add_global_handler('ping',mapUpd)

# Create a server object, connect and join the channel
server = irc.server()
server.connect ( network, port, nick, pass_, ircname = name )
server.join ( channel )
mapUpd('irc.freenode.org','#indiatwits')

# Jump into an infinite loop
irc.process_forever()